<template>
    <div id="Three3D" v-show="isSelfShow">
      <div class="webgl_container" ref="webgl_container">

      </div>
    </div>
</template>

<script>
    import BaseComponent from "../qtWebBridge/frame/vue/BaseComponent";
    import {COMPONENT_TYPE_MENU} from "../qtWebBridge/frame/FrameManager";
    import * as THREE from 'three';
    import Stats from "three/examples/jsm/libs/stats.module";
    import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls.js'

    export default {
      extends:BaseComponent,
      name: "Three3D",

      data() {
        return {
          component_type: COMPONENT_TYPE_MENU,
          unique_name:'Three3D',
          isSelfShow:false,
          three3DScene:null,
          three3DCamera:null,
          three3DRenderer:null,
          three3DStats:null,
          three3DTimer:null,
          three3DControls:null,
        }
      },
      methods:{
        onEnter() {
          if(!this.three3DScene) {
            this._initThreeScene();
            this._addObject();
          }
        },
        onExit() {
          // if(this.three3DScene) {
          //   let allChildren = this.three3DScene.children;
          //   console.log(allChildren)
          //   let numberOfObjects  = 0;
          //   for(let i in allChildren) {
          //     let item = allChildren[i];
          //     item.geometry.dispose() // 删除几何体
          //     item.material.dispose() // 删除材质
          //     this.three3DScene.remove(allChildren[i]);
          //     numberOfObjects ++;
          //   }
          //   this.three3DRenderer.renderLists.dispose();
          //   this.three3DRenderer.dispose();
          //   this.three3DRenderer.render( this.three3DScene, this.three3DCamera );
          //   console.log(numberOfObjects);
          // }
        },
        onMounted(){

        },
        onDestroyed() {
          cancelAnimationFrame(this.three3DTimer);
        },
        _initThreeScene() {
          let width = this.$refs.webgl_container.clientWidth;
          let height = this.$refs.webgl_container.clientHeight;
          // 场景-----------------------
          let scene = new THREE.Scene();
          this.three3DScene = scene;
          // --------------------------

          // 摄像机---------------------
          let camera = new THREE.PerspectiveCamera(90, width / height, 0.1, 1000);
          this.three3DCamera = camera;

          // 渲染器--------------------
          let renderer = new THREE.WebGLRenderer();
          this.three3DRenderer = renderer;
          renderer.setSize( width, height );
          this.$refs.webgl_container.appendChild(renderer.domElement)

          // 设置渲染器渲染阴影效果
          renderer.setClearColor(new THREE.Color(0x220000));
          renderer.setSize(width, height);
          renderer.shadowMap.enabled = true;

          // 状态监视器-------------------
          let stats = new Stats();
          this.three3DStats = stats;
          stats.showPanel( 0 );
          this.$refs.webgl_container.appendChild(stats.dom)
          // 状态监视器 end --------------
          //控制器
          this.three3DControls = new OrbitControls(this.three3DCamera, this.three3DRenderer.domElement);

          this._frameUpdate();
        },
        _frameUpdate() {
          this.three3DRenderer.render( this.three3DScene, this.three3DCamera );
          this.three3DTimer = requestAnimationFrame(this._frameUpdate)
        },
        _addObject() {
          this.three3DCamera.position.x = -30;
          this.three3DCamera.position.y = 40;
          this.three3DCamera.position.z = 30
          this.three3DCamera.lookAt(this.three3DScene.position);

          // 坐标轴--------------------
          let axes = new THREE.AxesHelper(50);
          this.three3DScene.add(axes);
          // -------------------------

          // 平面---------------------
          let planeGeometry = new THREE.PlaneGeometry(60, 20, 1, 1);
          let planeMaterial = new THREE.MeshLambertMaterial({color: 0xcccccc});
          let plane = new THREE.Mesh(planeGeometry, planeMaterial);
          plane.rotation.x = -0.5 * Math.PI;
          plane.position.x = 15
          plane.position.y = 0
          plane.position.z = 0
          this.three3DScene.add(plane);

          // 设置投影
          plane.receiveShadow = true;
          // --------------------------

          // 物体----------------------
          let geometry = new THREE.BoxGeometry(4, 4, 4);
          let material = new THREE.MeshLambertMaterial( { color: 0x00ff00} );
          let cube = new THREE.Mesh( geometry, material );
          cube.position.x = 0;
          cube.position.y = 2;
          cube.position.z = 0;

          // 设置投影
          cube.castShadow = true;
          this.three3DScene.add( cube );
          // 物体 end ------------------

          // 光源-----------------------
          let spotLight = new THREE.SpotLight( 0x3ffffff );
          spotLight.position.set( -40, 60, -10 );
          this.three3DScene.add( spotLight );

          // 设置投影
          spotLight.castShadow = true;
          // 光源 end -------------------
        }
      }
    }
</script>

<style scoped>
  #Three3D {
    display: flex;
    flex-grow: 1;
  }

.webgl_container {
  background: #32b7b9;
  flex-grow: 1;
}
</style>
